from flask import Blueprint, request, jsonify, current_app, g
from flask_jwt_extended import jwt_required, get_jwt_identity
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime

from models import db, User
from utils import EncryptionUtil, validate_email, validate_phone
from security_middleware import rate_limit, validate_input
from security_enhanced import enhanced_rate_limit, enhanced_validate_input

user_bp = Blueprint('user', __name__)

def create_response(success=True, message="", data=None, code=200):
    """创建统一的响应格式"""
    response_data = {
        'success': success,
        'message': message,
        'data': data,
        'timestamp': datetime.utcnow().isoformat()
    }
    
    return jsonify(response_data), code

def get_request_data():
    """获取解密后的请求数据"""
    return getattr(g, 'decrypted_data', {})

@user_bp.route('/profile', methods=['GET'])
@jwt_required()
def get_profile():
    """获取用户信息"""
    current_user_uuid = get_jwt_identity()
    user = User.query.filter_by(uuid=current_user_uuid).first()
    
    if not user:
        return create_response(False, "用户不存在", code=404)
    
    return create_response(True, "获取用户信息成功", user.to_dict())

@user_bp.route('/profile', methods=['PUT'])
@jwt_required()
@enhanced_rate_limit('update_profile')  # 使用增强的频率限制
@enhanced_validate_input()              # 使用增强的输入验证
def update_profile():
    """更新用户信息"""
    current_user_uuid = get_jwt_identity()
    user = User.query.filter_by(uuid=current_user_uuid).first()
    
    if not user:
        return create_response(False, "用户不存在", code=404)
    
    data = get_request_data()
    if not data:
        return create_response(False, "请求数据格式错误", code=400)
    
    # 更新允许的字段
    if 'nickname' in data:
        user.nickname = data['nickname']
    
    if 'email' in data:
        email = data['email']
        if email and not validate_email(email):
            return create_response(False, "邮箱格式不正确", code=400)
        
        # 检查邮箱是否已被其他用户使用
        if email and User.query.filter(User.email == email, User.id != user.id).first():
            return create_response(False, "邮箱已被使用", code=400)
        
        user.email = email
    
    if 'username' in data:
        username = data['username']
        if username and User.query.filter(User.username == username, User.id != user.id).first():
            return create_response(False, "用户名已被使用", code=400)
        
        user.username = username
    
    if 'avatar' in data:
        user.avatar = data['avatar']
    
    user.updated_at = datetime.utcnow()
    
    try:
        db.session.commit()
        return create_response(True, "用户信息更新成功", user.to_dict())
    except Exception as e:
        db.session.rollback()
        return create_response(False, f"更新失败: {str(e)}", code=500)

@user_bp.route('/change-password', methods=['POST'])
@jwt_required()
@enhanced_rate_limit('change_password')  # 使用增强的频率限制
@enhanced_validate_input()               # 使用增强的输入验证
def change_password():
    """修改密码"""
    current_user_uuid = get_jwt_identity()
    user = User.query.filter_by(uuid=current_user_uuid).first()
    
    if not user:
        return create_response(False, "用户不存在", code=404)
    
    data = get_request_data()
    if not data:
        return create_response(False, "请求数据格式错误", code=400)
    
    old_password = data.get('old_password')
    new_password = data.get('new_password')
    
    if not old_password or not new_password:
        return create_response(False, "旧密码和新密码不能为空", code=400)
    
    if len(new_password) < 6:
        return create_response(False, "新密码长度不能少于6位", code=400)
    
    # 验证旧密码
    if user.password_hash and not user.check_password(old_password):
        return create_response(False, "旧密码错误", code=400)
    
    # 设置新密码
    user.set_password(new_password)
    user.updated_at = datetime.utcnow()
    
    try:
        db.session.commit()
        return create_response(True, "密码修改成功")
    except Exception as e:
        db.session.rollback()
        return create_response(False, f"密码修改失败: {str(e)}", code=500)

@user_bp.route('/bind-phone', methods=['POST'])
@jwt_required()
def bind_phone():
    """绑定手机号"""
    current_user_uuid = get_jwt_identity()
    user = User.query.filter_by(uuid=current_user_uuid).first()
    
    if not user:
        return create_response(False, "用户不存在", code=404)
    
    data = get_request_data()
    if not data:
        return create_response(False, "请求数据格式错误", code=400)
    
    phone = data.get('phone')
    code = data.get('code')
    
    if not phone or not code:
        return create_response(False, "手机号和验证码不能为空", code=400)
    
    if not validate_phone(phone):
        return create_response(False, "手机号格式不正确", code=400)
    
    # 检查手机号是否已被使用
    if User.query.filter(User.phone == phone, User.id != user.id).first():
        return create_response(False, "手机号已被使用", code=400)
    
    # 验证短信验证码
    from models import SmsCode
    sms_code = SmsCode.query.filter_by(
        phone=phone,
        purpose='bind'
    ).order_by(SmsCode.created_at.desc()).first()
    
    if not sms_code or not sms_code.is_valid(code):
        return create_response(False, "验证码错误或已过期", code=400)
    
    # 绑定手机号
    user.phone = phone
    user.updated_at = datetime.utcnow()
    sms_code.used = True
    sms_code.user_id = user.id
    
    try:
        db.session.commit()
        return create_response(True, "手机号绑定成功", user.to_dict())
    except Exception as e:
        db.session.rollback()
        return create_response(False, f"绑定失败: {str(e)}", code=500)